#include "Storage/StorageBase.hpp"
#include "Storage/StorageCommand.hpp"
#include <cassert>
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
#include <boost/lambda/construct.hpp>
#include <boost/iterator/indirect_iterator.hpp>
#include <algorithm>

namespace Storage
{
	
StorageBase::~StorageBase()
{
	this->clearCommands();
}

// ---------------------------------------------------------------------------------------------------------------------

void StorageBase::pushCommand( StorageCommand* pNewCommand )
{
	assert( NULL != pNewCommand);
	commands_.push_back( pNewCommand);
}

// ---------------------------------------------------------------------------------------------------------------------

void StorageBase::store()
{
	boost::indirect_iterator< StorageCommands::iterator, StorageCommand&> cmdI( commands_.begin()),
		cmdEndI( commands_.end());
	while( cmdI != cmdEndI)
	{
		cmdI->execute();
		++cmdI;
	}
	this->clearCommands();
}

// ---------------------------------------------------------------------------------------------------------------------

void StorageBase::clearCommands()
{
	using namespace boost::lambda;
	std::for_each( commands_.begin(), commands_.end(), bind( delete_ptr(), _1));
	commands_.clear();
}

// ---------------------------------------------------------------------------------------------------------------------

const StorageCommand* StorageBase::topCommand() const
{
	return commands_.empty() ? NULL : commands_.back();
}

// ---------------------------------------------------------------------------------------------------------------------

StorageCommand* StorageBase::topCommand()
{
	return commands_.empty() ? NULL : commands_.back();
}

// ---------------------------------------------------------------------------------------------------------------------

StorageCommand* StorageBase::popCommand()
{
	if( commands_.empty())
	{
		return NULL;
	}
	else
	{
		StorageCommand* pResult = commands_.back();
		commands_.erase( --commands_.end());
		return pResult;
	}
}

// ---------------------------------------------------------------------------------------------------------------------

bool StorageBase::hasUnsavedChanges() const
{
	return !commands_.empty();
}

} // namespace Storage
